﻿using AutoMapper;
using B.S.BaseData.Domain;
using B.S.BaseData.ErrorCode;
using B.S.BaseData.Read.Api.Application.Command;
using B.S.BaseData.Read.Api.Dtos;
using MediatR;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.BaseData.Read.Api.Application.CommandHander
{
    /// <summary>
    /// 递归显示菜单命令执行
    /// </summary>
    public class GetTreeMenuCommandHandler : IRequestHandler<GetTreeMenuCommand, ApiResult<List<TreeMenuDTOs>>>
    {
        private readonly IMapper mapper;
        private readonly ISqlSugarClient db;

        public GetTreeMenuCommandHandler(IMapper mapper, ISqlSugarClient db)
        {
            this.mapper = mapper;
            this.db = db;
        }


        /// <summary>
        /// 全局用户id
        /// </summary>
        public int userId { get; set; }
        /// <summary>
        /// 总数
        /// </summary>
        public int Count { get; set; }

        /// <summary> 
        /// 递归显示菜单
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<ApiResult<List<TreeMenuDTOs>>> Handle(GetTreeMenuCommand request, CancellationToken cancellationToken)
        {
            try
            {
                userId = request.UserId;
                ApiResult<List<TreeMenuDTOs>> result = new ApiResult<List<TreeMenuDTOs>>();
                var data = await GetMenuTree(request.UserId);
                Count = data.Count;
                result.Msg = ApiEnum.显示成功.ToString();
                result.Data = data;
                return result;
            }
            catch (Exception ex)
            {
                // 处理异常
                return new ApiResult<List<TreeMenuDTOs>>
                {
                    Code = ApiEnum.显示失败, // 假设存在这个枚举值表示显示失败
                    Msg = $"查询菜单树时发生错误: {ex.Message}",
                    Data = null
                };
            }
        }

        /// <summary>
        /// 递归
        /// </summary>
        /// <param name="UserId"></param>
        /// <returns></returns>
        private async Task<List<TreeMenuDTOs>> GetMenuTree(int UserId)
        {
            // 查出用户的对应角色
            var userRoles = await db.Queryable<User>()
               .Where(x => x.UserId == UserId)
               .InnerJoin<UserRole>((u, ur) => u.UserId == ur.UserId)
               .InnerJoin<Role>((u, ur, r) => ur.RoleId == r.RoleId)
               .Select((u, ur, r) => new GetUserRole2Dto
               {
                   UserRoleId = ur.UserId,
                   RoleId = r.RoleId,
                   RoleName = r.RoleName,
                   UserId = u.UserId,
                   UserName = u.UserName,
               })
               .ToListAsync();

            var roleIds = userRoles.Select(r => r.RoleId).ToList();

            // 查出角色对应的菜单
            var menuIds = await db.Queryable<RoleMenu>()
               .Where(x => roleIds.Contains(x.RoleId))
               .Select(x => x.MenuId)
               .ToListAsync();

            // 递归构建菜单树
            return await BuildMenuTree(0, menuIds);
        }

        private async Task<List<TreeMenuDTOs>> BuildMenuTree(int parentId, List<int> menuIds)
        {
            var menus = await db.Queryable<Menu>()
               .Where(x => x.PId == parentId && menuIds.Contains(x.Id))
               .ToListAsync();

            var menuDtos = mapper.Map<List<TreeMenuDTOs>>(menus);

            foreach (var menuDto in menuDtos)
            {
                menuDto.children = await BuildMenuTree(menuDto.Id, menuIds);
            }

            return menuDtos;
        }
    }
}